<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/28 0028
 * Time: 上午 9:43
 */
namespace app\common\auth;

use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;
use think\facade\Config;

/**
 * JSON Web Token 身份验证
 * Class JwtAuth
 * @package app\common\auth
 */
class JwtAuth{
    /**
     * jwt token
     * @var
     */
    private $token;
    private $uid;

    private $decodeToken;
    /**
     * 单列模式 jwtAuth句柄
     * @var
     */
    private static $instance;

    public static function getInstance(){
        if(is_null(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct()
    {

    }

    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    /**
     * 获取token
     * @return string
     */
    public function getToken(){
        return (string)$this->token;
    }

    /**
     * 设置token
     * @param $token
     * @return $this
     */
    public function setToken($token){
        $this->token = $token;
        return $this;
    }

    /**
     * 设置uid
     * @param $uid
     * @return $this
     */
    public function setUid($uid){
        $this->uid = $uid;
        return $this;
    }

    /**
     * 编码jwt token
     * @return $this
     */
    public function encode(){
        $time = time();
        $this->token = (new Builder())->setHeader('alg','HS256')
            ->setIssuer(Config::get('jwt.iss'))
            ->setAudience(Config::get('jwt.aud'))
            ->setIssuedAt($time)
            ->setExpiration($time + Config::get('jwt.expire_time'))
            ->set('uid',$this->uid)
            ->sign(new Sha256(),Config::get('jwt.secrect'))
            ->getToken();
        return $this;
    }

    /**
     * verify token 验证token
     * @return bool
     */
    public function verify(){
        $result = $this->decode()->verify(new Sha256(),Config::get('jwt.secrect'));
        return $result;
    }

    /**
     * 验证信息是否被篡改
     * @return bool
     */
    public function validate(){
        $data = new ValidationData();
        $data->setIssuer(Config::get('jwt.iss'));
        $data->setAudience(Config::get('jwt.aud'));
        return $this->decode()->validate($data);
    }

    /**
     * 解码jwt token
     * @return \Lcobucci\JWT\Token
     */
    public function decode(){
        if(!$this->decodeToken){
            $this->decodeToken = (new Parser())->parse((string)$this->token);
            $this->uid = $this->decodeToken->getClaim('uid');
        }
        return $this->decodeToken;
    }
}